﻿using System;
using System.Net;
using System.Windows;
using System.Text;
using System.IO;
using System.Windows.Threading;

namespace Studio77.PopBall.Utils
{
    public class WPWebClient
    {
        //载入数据成功后的委托
        public delegate void DownLoadDataCompleted(object sender, DownloadStringCompletedEventArgs e);
        public DownLoadDataCompleted OnDownLoadDataCompleted;

        public delegate void UpLoadDataCompleted(object sender, UploadStringCompletedEventArgs e);
        public UpLoadDataCompleted OnUpLoadDataCompleted;

        public delegate void OpenReadCompleted(object sender, OpenReadCompletedEventArgs e);
        public OpenReadCompleted OnOpenReadCompleted;
        
        public delegate void WriteStreamClosed(object sender, WriteStreamClosedEventArgs e);
        public WriteStreamClosed OnWriteStreamClosed;

        private WebClient mWebClient = new WebClient();
        public DispatcherTimer connectServerTimer = null;
        public RequestMethod requestMethod = RequestMethod.METHOD_POST;
        public string sendData = string.Empty;
        public string httpUrl = string.Empty;
        public bool isNeedCache = false;                //返回的结果是否需要保存
        public string timeOut = "10";                   //设置超时时间 秒为单位

        /// <summary>
        /// 设置请求head
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public string SetHeader(string key, string value)
        {
            if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value))
            {
                return WPResultCode.RESULT_HEADER_KEY_OR_VALUE_NULL;
            }

            mWebClient.Headers[key] = value;
            return WPResultCode.RESTLT_OK;
        }

        /// <summary>
        /// 获取请求head
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string GetHeader(string key)
        {
            if (string.IsNullOrEmpty(key))
            {
                return null;
            }

            return mWebClient.Headers[key];
        }

        /// <summary>
        /// 获取全部的head集
        /// </summary>
        /// <returns></returns>
        public WebHeaderCollection GetHeaders()
        {
            return mWebClient.Headers;
        }

        /// <summary>
        /// 获取返回的head集
        /// </summary>
        /// <returns></returns>
        public WebHeaderCollection GetResponseHeaders()
        {
            return mWebClient.ResponseHeaders;
        }

        /// <summary>
        /// 设置请求的encoding
        /// </summary>
        /// <param name="eCoding"></param>
        /// <returns></returns>
        public string SetEncoding(Encoding eCoding)
        {
            try
            {
                mWebClient.Encoding = eCoding;
                return WPResultCode.RESTLT_OK;
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        /// <summary>
        /// 获取请求的encoding
        /// </summary>
        /// <returns></returns>
        public Encoding GetEncoding()
        {
            try
            {
                return mWebClient.Encoding;
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        /// <summary>
        /// 设置请求的方法 GET POST
        /// </summary>
        /// <param name="reMethod"></param>
        public void SetRequestMethod(RequestMethod reMethod)
        {
            requestMethod = reMethod;
        }

        /// <summary>
        /// 获取请求的方法 GET POST
        /// </summary>
        /// <returns></returns>
        public RequestMethod GetRequestMethod()
        {
            return requestMethod;
        }

        /// <summary>
        /// 设置请求的目标地址
        /// </summary>
        /// <param name="url"></param>
        public void SetHttpUrl(string url)
        {
            httpUrl = url;
        }

        /// <summary>
        /// 设置超时时间 秒单位
        /// </summary>
        /// <param name="time"></param>
        public void SetTimeOut(string time)
        {
            timeOut = time;
        }

        /// <summary>
        /// 设置请求包
        /// </summary>
        /// <param name="requestData"></param>
        public void SetRequestData(WPRequestData requestData)
        {
            requestMethod = requestData.requestMethod;
            isNeedCache = requestData.isNeedCache;

            if (!string.IsNullOrEmpty(requestData.httpUrl))
            {
                httpUrl = requestData.httpUrl;
            }
            if(!string.IsNullOrEmpty(requestData.sendData))
            {
                sendData = requestData.sendData;
            }
            if(!string.IsNullOrEmpty(requestData.timeOut))
            {
                timeOut = requestData.timeOut;
            }
        }

        /// <summary>
        /// 是否正在请求忙碌状态
        /// </summary>
        /// <returns></returns>
        public bool IsBusy()
        {
            return mWebClient.IsBusy;
        }

        /// <summary>
        /// 取消请求
        /// </summary>
        public void RequestCancel()
        {
            try
            {
                mWebClient.CancelAsync();
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        public string GetRequestHttpUrl(string httpUrl, string sendData)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(httpUrl);
            sb.Append(sendData);
            //if (string.IsNullOrEmpty(sendData))
            //{
            //    sb.Append("?");
            //    sb.Append(Guid.NewGuid().ToString());
            //}
            //else
            //{
            //    sb.Append("&");
            //    sb.Append(Guid.NewGuid().ToString());
            //}

            return sb.ToString();
        }

        /// <summary>
        /// 连接服务器 并发送Get Post请求
        /// </summary>
        /// <param name="requestData"></param>
        public void Connection(WPRequestData requestData, bool isStringType)
        {
            SetRequestData(requestData);
            
            //请求方式
            if (requestMethod == RequestMethod.METHOD_GET)
            {
                string s = sendData.Substring(0, sendData.Length >= 37 ? sendData.Length - 37 : sendData.Length);

                if (isStringType)
                {
                    //ConnectServerTimer();
                    GetDataType();
                }
                else
                {
                    OpenReadDataType();
                }
            }
            else
            {
                if (isStringType)
                {
                    //ConnectServerTimer();
                    PostDataType();
                }
                else
                {
                    OpenWriteDataType();
                }
            }
        }

        /// <summary>
        /// 获取数据Get方法
        /// </summary>
        private void GetDataType()
        {
            try
            {
                mWebClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(WebClient_DownloadStringCompleted);
                mWebClient.DownloadStringAsync(new Uri(GetRequestHttpUrl(httpUrl, sendData)));
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 发数据 Post方法
        /// </summary>
        private void PostDataType()
        {
            try
            {
                mWebClient.UploadStringCompleted += new UploadStringCompletedEventHandler(WebClient_UploadStringCompleted);
                mWebClient.UploadStringAsync(new Uri(GetRequestHttpUrl(httpUrl, null)), sendData);
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 下载字符型数据 对应Get方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                if (isNeedCache)
                {
                    //todo cache
                }
                this.OnDownLoadDataCompleted(sender, e);
            }
            catch (Exception ex)
            {
            }
        }

        /// <summary>
        /// 上传数据 Post方法的
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebClient_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
        {
            try
            {
                if (isNeedCache)
                {
                    //todo cache
                }
                this.OnUpLoadDataCompleted(sender, e);
            }
            catch (Exception ex)
            {
            }
        }

        private void OpenReadDataType()
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(httpUrl);
            sb.Append(sendData);

            try
            {
                mWebClient.OpenReadCompleted += new OpenReadCompletedEventHandler(WebClient_OpenReadCompleted);
                mWebClient.OpenReadAsync(new Uri(sb.ToString()));
            }
            catch (Exception)
            {
                //throw (ex);
            }
        }

        private void OpenWriteDataType()
        {
            try
            {
                mWebClient.OpenWriteCompleted += new OpenWriteCompletedEventHandler(WebClient_OpenWriteCompleted);
                mWebClient.OpenWriteAsync(new Uri(httpUrl), "POST", sendData);
                mWebClient.WriteStreamClosed += new WriteStreamClosedEventHandler(Webclient_WriteStreamClosed);
            }
            catch (Exception)
            {
                //throw (ex);
            }
        }

        private void WebClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            try
            {
                if (isNeedCache)
                {
                    //todo cache
                }
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                { this.OnOpenReadCompleted(sender, e); });
            }
            catch (Exception)
            {
                //throw (ex);
            }
        }

        private void WebClient_OpenWriteCompleted(object sender, OpenWriteCompletedEventArgs e)
        {
            //将数据流发送到服务器上
            try
            {
                //　e.UserState　-　需要上传的流（客户端流）
                Stream clientStream = e.UserState as Stream;
                //　e.Result　-　目标地址的流（服务端流）
                Stream serverStream = e.Result;
                byte[] buffer = new byte[4096];
                int readcount = 0;
                //　clientStream.Read　-　将需要上传的流读取到指定的字节数组中
                while ((readcount = clientStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    //　serverStream.Write　-　将指定的字节数组写入到目标地址的流
                    serverStream.Write(buffer, 0, readcount);
                }
                serverStream.Close();
                clientStream.Close();
            }
            catch (Exception)
            {
                //throw (ex);
            }
        }

        private void Webclient_WriteStreamClosed(object sender, WriteStreamClosedEventArgs e)
        {
            try
            {
                if (isNeedCache)
                {
                    //todo cache
                }
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                { this.OnWriteStreamClosed(sender, e); });
                //this.OnWriteStreamClosed(sender, e);
            }
            catch (Exception)
            {
                //throw (ex);
            }
        }

        /// <summary>
        /// 服务器连接超时的定时器 
        /// </summary>
        private void ConnectServerTimer()
        {
            if (null == connectServerTimer)
            {
                connectServerTimer = new DispatcherTimer();
                //创建间隔时间
                connectServerTimer.Interval = new TimeSpan(0, 0, int.Parse(timeOut));
                connectServerTimer.Tick += new EventHandler(ConnectServerTick);
            }
            connectServerTimer.Stop();
            connectServerTimer.Start();
        }

        /// <summary>
        /// 超时响应
        /// </summary>
        /// <param name="o"></param>
        /// <param name="sender"></param>
        private void ConnectServerTick(object o, EventArgs sender)
        {
            connectServerTimer.Stop();
            try
            {
                mWebClient.CancelAsync();
            }
            catch (Exception)
            {
                //throw (ex);
            }
        }
    }
}
